package util.mail;

import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import javax.activation.DataHandler;
import javax.activation.FileDataSource;
import javax.mail.Authenticator;
import javax.mail.Message;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class MailSendUtil {

	public static List<String[]> sendMail(List<MailInfo> infos) {
		List<String[]> list = new ArrayList<>();
		for (MailInfo info : infos) {
			String[] res = new String[2];
			try {
				sendMail(info);
				res[0] = info.getToAddress();
			} catch (MessagingException e) {
				res[1] = e.getMessage();
				e.printStackTrace();
			} catch (Exception e) {
				res[1] = e.getMessage();
				e.printStackTrace();
			}
			list.add(res);
		}
		return list;
	}

	public static void sendMail(MailInfo info) throws MessagingException,
			Exception {
		Transport.send(getMessage(info));
	}

	public static Message getMessage(MailInfo info) throws Exception {
		final Properties p = System.getProperties();
		p.setProperty("mail.smtp.host", info.getHost());
		p.setProperty("mail.smtp.auth", "true");
		p.setProperty("mail.smtp.user", info.getFormName());
		p.setProperty("mail.smtp.pass", info.getFormPassword());
		// new Authenticator()应该是验证密码如果没有加的话会报
		// failed to connect, no password specified?错误
		Session session = Session.getInstance(p, new Authenticator() {
			protected PasswordAuthentication getPasswordAuthentication() {
				return new PasswordAuthentication(p
						.getProperty("mail.smtp.user"), p
						.getProperty("mail.smtp.pass"));
			}
		});
		session.setDebug(true);
		Message message = new MimeMessage(session);
		message.setSubject(info.getSubject());
		message.setReplyTo(InternetAddress.parse(info.getReplayAddress()));
		message.setFrom(new InternetAddress(p.getProperty("mail.smtp.user"),
				"WSF"));
		message.setRecipient(RecipientType.TO,
				new InternetAddress(info.getToAddress()));
		// 创建邮件的各个 MimeBodyPart 部分
		// 将邮件中各个部分组合到一个"mixed"型的 MimeMultipart 对象
		MimeMultipart allPart = new MimeMultipart("mixed");
		if (info.getFileUrl() != null && info.getFileUrl().length > 0) {
			for (String fileUrl : info.getFileUrl())
				allPart.addBodyPart(createAttachment(fileUrl));
		}

		MimeBodyPart content = createContent(info);
		allPart.addBodyPart(content);

		// 将上面混合型的 MimeMultipart 对象作为邮件内容并保存
		message.setContent(allPart);
		message.saveChanges();
		return message;
	}

	/**
	 * 根据传入的文件路径创建附件并返回
	 */
	private static MimeBodyPart createAttachment(String fileName)
			throws Exception {
		MimeBodyPart attachmentPart = new MimeBodyPart();
		FileDataSource fds = new FileDataSource(fileName);
		attachmentPart.setDataHandler(new DataHandler(fds));
		attachmentPart.setFileName(fds.getName());
		return attachmentPart;
	}

	/**
	 * 根据传入的邮件正文body和文件路径创建图文并茂的正文部分
	 */
	private static MimeBodyPart createContent(MailInfo info) throws Exception {
		// 用于保存最终正文部分
		MimeBodyPart contentBody = new MimeBodyPart();
		// 用于组合文本和图片，"related"型的MimeMultipart对象
		MimeMultipart contentMulti = new MimeMultipart("related");

		// 正文的文本部分
		MimeBodyPart textBody = new MimeBodyPart();
		textBody.setContent(info.getContent(), "text/html;charset=utf-8");
		contentMulti.addBodyPart(textBody);

		// 正文的图片部分
		MimeBodyPart jpgBody = new MimeBodyPart();
		FileDataSource fds = new FileDataSource(info.getContentImage());
		jpgBody.setDataHandler(new DataHandler(fds));
		// jpgBody.setFileName(fds.getName());没有设置正文图片名字则不会在正文中显示该图片并且会变成附件中后缀名为.bin的该正文图片文件
		jpgBody.setFileName(fds.getName());
		jpgBody.setContentID(info.getContentImageID());
		contentMulti.addBodyPart(jpgBody);

		// 将上面"related"型的 MimeMultipart 对象作为邮件的正文
		contentBody.setContent(contentMulti);
		return contentBody;
	}

}
